package world.criver.imagecompresstool.contorller;

import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventTarget;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.AccessibleAttribute;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.*;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import world.criver.imagecompresstool.application.appPop;
import world.criver.imagecompresstool.data.daConfig;
import world.criver.imagecompresstool.data.daValue;
import world.criver.imagecompresstool.function.*;
import world.criver.imagecompresstool.modular.moRow;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.net.URL;
import java.util.*;

public class conMaster implements Initializable{
    public AnchorPane ap;
    public Label menu1;
    public Label menu2;
    public Label menu3;
    private int scene_id=1;
    private double press_x=-1,press_y=-1;
    private funHotKey funHotKey=new funHotKey();
    public void onWindowMin(MouseEvent e) {
        daValue.master.setIconified(true);
    }

    public void onWindowClose(MouseEvent e) {
        daValue.master.hide();
    }

    public void onMenu1() {
        updateMenuState(1);
        createScene1();
    }

    public void onMenu2() {
        updateMenuState(2);
        createScene2();
    }

    public void onMenu3() {
        updateMenuState(3);
        createScene3();
    }
    public void onTitlePress(MouseEvent e){
        press_x=e.getScreenX()-daValue.master.getX();
        press_y=e.getScreenY()-daValue.master.getY();

    }
    public void onTitleDrag(MouseEvent e){
        daValue.master.setX(e.getScreenX()-press_x);
        daValue.master.setY(e.getScreenY()-press_y);
    }

    public void onDragDrop(DragEvent e) {
        if (scene_id == 3) return;
        ap.getParent().setStyle("-fx-background-color: #00000000");
        List<File> fs = e.getDragboard().getFiles();
        funCache funCache = new funCache();
        for (File f : fs)
            if(f.isFile() && (f.getName().endsWith(".png")||f.getName().endsWith(".jpg")))
                funCache.add(new String[]{"mode:" + (scene_id==1?daConfig.mode_compress:daConfig.mode_ico), "file:" + f.getPath()});
    }

    public void onDragEnter(DragEvent e) {
        if(scene_id==3)return;
        ap.getParent().setStyle("-fx-background-color: #00000011");
    }
    public void onDragOver(DragEvent e){
        if(e.getDragboard().hasFiles())e.acceptTransferModes(TransferMode.MOVE);
        else e.consume();
    }

    /**
     * 创建压缩界面
     */
    private void createScene1(){
        ap.getChildren().clear();
        Label tip=new Label("拖入图片,开始压缩");
        tip.setTextFill(new Color(0,0,0,0.1));
        tip.setFont(new Font(24));
        tip.setPrefWidth(300);
        tip.setPrefHeight(220);
        tip.setAlignment(Pos.CENTER);
        ap.getChildren().add(tip);
        VBox vb=new VBox();
        vb.setSpacing(4);
        ap.getChildren().add(vb);
    }
    private void createScene2(){
        ap.getChildren().clear();
        Label tip=new Label("拖入图片,开始转Icon");
        tip.setTextFill(new Color(0,0,0,0.1));
        tip.setFont(new Font(24));
        tip.setPrefWidth(300);
        tip.setPrefHeight(220);
        tip.setAlignment(Pos.CENTER);
        ap.getChildren().add(tip);
        VBox vb=new VBox();
        vb.setSpacing(4);
        ap.getChildren().add(vb);
    }
    private void createScene3(){
        ap.getChildren().clear();
        VBox box=new VBox();
        box.setSpacing(4);
        ap.getChildren().add(box);

        Color gray=new Color(0,0,0,0.6);

        //压缩设置
        Label title1=new Label("压缩设置");
        title1.setFont(new Font(16));
        title1.setTextFill(gray);
        box.getChildren().add(title1);
        HBox l10=new HBox();
        l10.setSpacing(8);
        box.getChildren().add(l10);
        RadioButton l11=new RadioButton("普通品质");
        l11.setSelected(daConfig.mode_compress.equals("compress1"));
        l11.setOnAction(e->{settingUpdateModeCompress(e);});
        l10.getChildren().add(l11);
        RadioButton l12=new RadioButton("高品质");
        l12.setSelected(daConfig.mode_compress.equals("compress2"));
        l12.setOnAction(e->{settingUpdateModeCompress(e);});
        l10.getChildren().add(l12);
        RadioButton l13=new RadioButton("低品质");
        l13.setSelected(daConfig.mode_compress.equals("compress3"));
        l13.setOnAction(e->{settingUpdateModeCompress(e);});
        l10.getChildren().add(l13);
        CheckBox l14=new CheckBox("替换原图");
        l14.setSelected(daConfig.compress_replace);
        l14.setOnAction(e->{settingUpdateReplaceCompress(e);});
        box.getChildren().add(l14);

        //转Ico设置
        Label title2=new Label("转Ico设置");
        title2.setFont(new Font(16));
        title2.setTextFill(gray);
        box.getChildren().add(title2);
        VBox l20=new VBox();
        l20.setSpacing(4);
        box.getChildren().add(l20);
        RadioButton l21=new RadioButton("自适应尺寸");
        l21.setSelected(daConfig.mode_ico.equals("ico1"));
        l21.setOnAction(e->{settingUpdateModeIco(e);});
        l20.getChildren().add(l21);
        HBox l201=new HBox();
        l201.setSpacing(8);
        l20.getChildren().add(l201);
        RadioButton l22=new RadioButton("16x16 px");
        l22.setSelected(daConfig.mode_ico.equals("ico2"));
        l22.setOnAction(e->{settingUpdateModeIco(e);});
        l201.getChildren().add(l22);
        RadioButton l23=new RadioButton("32x32 px");
        l23.setSelected(daConfig.mode_ico.equals("ico3"));
        l23.setOnAction(e->{settingUpdateModeIco(e);});
        l201.getChildren().add(l23);
        RadioButton l24=new RadioButton("48x48 px");
        l24.setSelected(daConfig.mode_ico.equals("ico4"));
        l24.setOnAction(e->{settingUpdateModeIco(e);});
        l201.getChildren().add(l24);
        HBox l202=new HBox();
        l202.setSpacing(8);
        l20.getChildren().add(l202);
        RadioButton l25=new RadioButton("64x64 px");
        l25.setSelected(daConfig.mode_ico.equals("ico5"));
        l25.setOnAction(e->{settingUpdateModeIco(e);});
        l202.getChildren().add(l25);
        RadioButton l26=new RadioButton("128x128 px");
        l26.setSelected(daConfig.mode_ico.equals("ico6"));
        l26.setOnAction(e->{settingUpdateModeIco(e);});
        l202.getChildren().add(l26);
        RadioButton l27=new RadioButton("256x256 px");
        l27.setSelected(daConfig.mode_ico.equals("ico7"));
        l27.setOnAction(e->{settingUpdateModeIco(e);});
        l202.getChildren().add(l27);

        //其他设置
        Label title3=new Label("其他设置");
        title3.setFont(new Font(16));
        title3.setTextFill(gray);
        box.getChildren().add(title3);
        CheckBox l31=new CheckBox();
        l31.setText("开机自启");
        l31.setSelected(daConfig.bootstrap);
        l31.setOnAction((e)->{
            daConfig.bootstrap=((CheckBox)e.getTarget()).isSelected();
            daConfig.save();
        });
        box.getChildren().add(l31);
        CheckBox l32=new CheckBox();
        l32.setText("右键菜单");
        l32.setSelected(daConfig.content_menu);
        l32.setOnAction((e)->{
            daConfig.content_menu=((CheckBox)e.getTarget()).isSelected();
            daConfig.save();
        });
        box.getChildren().add(l32);
        CheckBox l33=new CheckBox();
        l33.setText("启动软件时打开窗口");
        l33.setSelected(daConfig.show_master);
        l33.setOnAction((e)->{
            daConfig.show_master=((CheckBox)e.getTarget()).isSelected();
            daConfig.save();
        });
        box.getChildren().add(l33);
        HBox h34=new HBox();
        h34.setAlignment(Pos.CENTER_LEFT);
        CheckBox l34=new CheckBox();
        l34.setSelected(daConfig.color_picker);
        l34.setText("全屏取色 热键:");
        l34.setOnAction((e)->{
            daConfig.color_picker=((CheckBox)e.getTarget()).isSelected();
            daConfig.save();
            if(daConfig.color_picker)funHotKey.addHook();
            else funHotKey.removeHook();
        });
        h34.getChildren().add(l34);
        TextField t34=new TextField(daConfig.color_picker_hot_key);
        t34.setEditable(false);
        t34.setOnMouseClicked(e->{
            t34.setText("");
        });
        t34.setOnKeyPressed(e->{
            if(e.getCode().getName().equals("Undefined"))return;
            System.out.println(e.getCode().getName());
            String qwe=t34.getText();
            if(qwe.isEmpty())qwe=e.getCode().getName();
            else qwe+="+"+e.getCode().getName();
            if(!funHotKey.isHotkeyCorrect(qwe))return;
            t34.setText(qwe);
            if(!funHotKey.isHotkeyEnd(qwe))return;
            daConfig.color_picker_hot_key=qwe;
            daConfig.save();
            l34.requestFocus();
        });
        h34.getChildren().add(t34);
        box.getChildren().add(h34);
    }

    /**
     * 更改压缩设置品质设置
     * @param e
     */
    private void settingUpdateModeCompress(ActionEvent e){
        RadioButton self= (RadioButton) e.getTarget();
        HBox vb= (HBox) self.getParent();
        for(int i=0;i<vb.getChildren().size();i++){
            ((RadioButton)vb.getChildren().get(i)).setSelected(false);
            if(vb.getChildren().get(i) ==self)daConfig.mode_compress="compress"+(i+1);
        }
        self.setSelected(true);
        daConfig.save();
    }
    private void settingUpdateReplaceCompress(ActionEvent e){
        CheckBox c= (CheckBox) e.getTarget();
        daConfig.compress_replace=c.isSelected();
        daConfig.save();
    }

    /**
     * 更改转ico设置
     * @param e
     */
    private void settingUpdateModeIco(ActionEvent e){
        RadioButton r= (RadioButton) e.getTarget();
        VBox vb=null;
        if(r.getParent() instanceof VBox)vb= (VBox) r.getParent();
        else vb= (VBox) r.getParent().getParent();
        int n=0;
        for(int i=0;i<vb.getChildren().size();i++){
            if(vb.getChildren().get(i) instanceof RadioButton){
                ((RadioButton)vb.getChildren().get(i)).setSelected(false);
                n++;
                if(vb.getChildren().get(i)==r)daConfig.mode_ico="ico"+n;
            }else{
                HBox hb= (HBox) vb.getChildren().get(i);
                for(int j=0;j<hb.getChildren().size();j++){
                    n++;
                    ((RadioButton)hb.getChildren().get(j)).setSelected(false);
                    if(hb.getChildren().get(j)==r)daConfig.mode_ico="ico"+n;
                }
            }
        }
        r.setSelected(true);
        daConfig.save();
    }
    private void updateMenuState(int num){
        scene_id=num;
        if(num==1)menu1.getStyleClass().add("menu_item_selected");
        else menu1.getStyleClass().remove("menu_item_selected");
        if(num==2)menu2.getStyleClass().add("menu_item_selected");
        else menu2.getStyleClass().remove("menu_item_selected");
        if(num==3)menu3.getStyleClass().add("menu_item_selected");
        else menu3.getStyleClass().remove("menu_item_selected");
    }

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        Platform.runLater(()->{
            daValue.conMaster=conMaster.this;
            onMenu1();
            new Timer().schedule(new listenClipboard(),new Date(),500);
            if(daConfig.color_picker)funHotKey.addHook();
        });
    }
    private String open_file="";
    private class listenClipboard extends TimerTask {
        @Override
        public void run() {
            Platform.runLater(()-> {
                File d=new File("cache");
                if(!d.exists() || d.isFile())return;
                File[] ds=d.listFiles();
                if(ds.length==0)return;
                if(ds[0].getName().equals(open_file))return;
                open_file=ds[0].getName();
                try(BufferedReader re=new BufferedReader(new FileReader(ds[0]))){
                    String a,b="";
                    while((a=re.readLine())!=null)b+=a+"\n";
                    daValue.commands=b.split("\n");
                }catch (Exception e){
                    throw new RuntimeException(e);
                }
                if(daValue.commands==null)return;
                String mode=null;
                String fs=null;
                long id=System.nanoTime();
                for(String i:daValue.commands){
                    if(i.contains("mode:"))mode=i.substring(5);
                    if(i.contains("file:"))fs=i.substring(5);
                }
                Thread.startVirtualThread(new pictureProcessing(id,mode,fs));
                daValue.commands=null;
                open_file="";
                ds[0].delete();
            });
        }
    }

    private void addLine(long id,File f) {
        Platform.runLater(() -> {
            VBox vb = (VBox) ap.getChildren().get(1);
            HBox hb = new HBox();//300
            hb.setPrefWidth(300);
            hb.getStyleClass().add("line");
            hb.setId(id + "");
            Label name = new Label(f.getName());
            name.setPrefWidth(80);
            name.setMaxWidth(80);
            name.setTextFill(new Color(0, 0, 0, 0.6));
            hb.getChildren().add(name);
            Tooltip tip = new Tooltip(f.getName());
            Tooltip.install(name, tip);
            Label os = new Label(new funSize().countFileSize(f));
            os.setPrefWidth(70);
            os.setAlignment(Pos.CENTER_RIGHT);
            os.setTextFill(new Color(0, 0, 0, 0.5));
            hb.getChildren().add(os);
            Label im = new Label(">");
            im.setPrefWidth(10);
            im.setAlignment(Pos.CENTER);
            im.setTextFill(new Color(0, 0, 0, 0.5));
            hb.getChildren().add(im);
            vb.getChildren().add(hb);
        });
    }
    private class pictureProcessing implements Runnable {
        private String mode=null,path=null;
        private long id;
        public pictureProcessing(long id,String mode,String path){
            this.mode=mode;
            this.path=path;
            this.id=id;
        }
        @Override
        public void run() {
            if(mode==null || path==null)return;
            File o=new File(path);
            if(!o.exists() || o.isDirectory())return;
            if(scene_id==1 || scene_id==2)addLine(id,o);
            ArrayList<String[]> result=new ArrayList<>();
            if(mode.contains("compress"))result=new funThumb().thumb(o,mode);
            else if(mode.contains("ico"))result=new funIcon().toIcon(o,mode);
            for(String[] s:result){
                Platform.runLater(()->{
                    try {
                        if(scene_id==1 || scene_id==2){
                            VBox vb= (VBox) ap.getChildren().get(1);
                            Node n=vb.lookup("#"+id);
                            if(n!=null){
                                boolean ok=s[2].equals("true");
                                HBox hb= (HBox) n;
                                Label im= (Label) hb.getChildren().get(2);
                                im.setText(ok?">":"x");
                                im.setTextFill(ok?new Color(0.1,1,0.09,1):new Color(1,0.65,0.65,1));
                                Label nn=new Label(new funSize().numToStr(Long.parseLong(s[4])));
                                nn.setTextFill(new Color(0,0,0,0.5));
                                nn.setPrefWidth(70);
                                hb.getChildren().add(nn);
                                Label pp=new Label(String.format("%.2f",(1-Long.parseLong(s[4])*1.0/Long.parseLong(s[1]))*100)+"%");
                                pp.setTextFill(new Color(0,0,0,0.5));
                                pp.setPrefWidth(50);
                                pp.setAlignment(Pos.CENTER_RIGHT);
                                hb.getChildren().add(pp);
                            }
                        }
                        new appPop(id,mode,s).start(new Stage());
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                });
            }
        }
    }
}
